import { ExtractionTask, ExtractionResult } from '../types';
import { EventEmitter } from 'events';

export class DataProcessor extends EventEmitter {
  private task: ExtractionTask;
  private results: ExtractionResult[];

  constructor(task: ExtractionTask) {
    super();
    this.task = task;
    this.results = [];
  }

  /**
   * 添加解析结果
   * @param result 解析结果
   */
  public addResult(result: ExtractionResult): void {
    this.results.push(result);
  }

  /**
   * 处理所有结果
   */
  public async process(): Promise<ExtractionResult> {
    try {
      // 合并所有结果
      const mergedResult = this.mergeResults();

      // 分析覆盖率
      const coverageAnalysis = this.analyzeCoverage(mergedResult);

      // 分析使用情况
      const usageAnalysis = this.analyzeUsage(mergedResult);

      // 分析模块分布
      const moduleAnalysis = this.analyzeModules(mergedResult);

      // 分析质量
      const qualityAnalysis = this.analyzeQuality(mergedResult);

      // 生成建议
      const suggestions = this.generateSuggestions(mergedResult);

      // 更新结果
      mergedResult.analysis = {
        coverage: coverageAnalysis,
        usage: usageAnalysis,
        modules: moduleAnalysis,
        quality: qualityAnalysis
      };
      mergedResult.suggestions = suggestions;

      // 触发处理完成事件
      this.emit('processingCompleted', mergedResult);

      return mergedResult;

    } catch (error) {
      // 触发处理错误事件
      this.emit('processingError', error);
      throw error;
    }
  }

  /**
   * 合并所有结果
   */
  private mergeResults(): ExtractionResult {
    if (this.results.length === 0) {
      return this.createEmptyResult();
    }

    const mergedResult = { ...this.results[0] };
    mergedResult.statistics = {
      totalFiles: 0,
      processedFiles: 0,
      extractedKeys: 0,
      errors: 0,
      processingTime: 0
    };

    // 合并统计信息
    for (const result of this.results) {
      mergedResult.statistics.totalFiles += result.statistics.totalFiles;
      mergedResult.statistics.processedFiles += result.statistics.processedFiles;
      mergedResult.statistics.extractedKeys += result.statistics.extractedKeys;
      mergedResult.statistics.errors += result.statistics.errors;
      mergedResult.statistics.processingTime += result.statistics.processingTime;
    }

    // 合并翻译键
    for (const result of this.results) {
      for (const translation of result.translations) {
        const existingTranslation = mergedResult.translations.find(t => t.key === translation.key);
        if (!existingTranslation) {
          mergedResult.translations.push(translation);
        } else {
          // 更新使用频率
          existingTranslation.frequency += translation.frequency;
          // 合并标签
          existingTranslation.tags = Array.from(new Set([...existingTranslation.tags, ...translation.tags]));
          // 合并翻译内容
          existingTranslation.translations = this.mergeTranslations(
            existingTranslation.translations,
            translation.translations
          );
        }
      }
    }

    // 合并错误信息
    mergedResult.errors = this.results.reduce((errors, result) => {
      return [...errors, ...result.errors];
    }, [] as ExtractionResult['errors']);

    return mergedResult;
  }

  /**
   * 合并翻译内容
   * @param existingTranslations 现有翻译
   * @param newTranslations 新翻译
   */
  private mergeTranslations(
    existingTranslations: Array<{ language: string; value: string; status: 'valid' | 'invalid' | 'missing' }>,
    newTranslations: Array<{ language: string; value: string; status: 'valid' | 'invalid' | 'missing' }>
  ): Array<{ language: string; value: string; status: 'valid' | 'invalid' | 'missing' }> {
    const merged = new Map<string, { language: string; value: string; status: 'valid' | 'invalid' | 'missing' }>();
    
    // 添加现有翻译
    existingTranslations.forEach(t => merged.set(t.language, t));
    
    // 添加或更新新翻译
    newTranslations.forEach(t => {
      const existing = merged.get(t.language);
      if (!existing || existing.status === 'missing') {
        merged.set(t.language, t);
      }
    });
    
    return Array.from(merged.values());
  }

  /**
   * 分析覆盖率
   * @param result 合并后的结果
   */
  private analyzeCoverage(result: ExtractionResult): ExtractionResult['analysis']['coverage'] {
    const coverage = {
      overall: 0,
      byLanguage: {} as Record<string, number>,
      byModule: {} as Record<string, number>,
      missingKeys: [] as string[],
      redundantKeys: [] as string[]
    };

    // 计算语言覆盖率
    const totalKeys = Object.keys(result.translations).length;
    if (totalKeys > 0) {
      for (const language of this.task.languages) {
        const translatedKeys = Object.values(result.translations).filter(
          translation => translation.translations[language]?.status === 'valid'
        ).length;
        coverage.byLanguage[language] = (translatedKeys / totalKeys) * 100;
      }

      // 计算整体覆盖率
      coverage.overall = Object.values(coverage.byLanguage).reduce(
        (sum, value) => sum + value,
        0
      ) / this.task.languages.length;
    }

    // 计算模块覆盖率
    const moduleKeys = new Map<string, number>();
    const moduleTranslatedKeys = new Map<string, number>();

    for (const translation of Object.values(result.translations)) {
      const module = translation.module;
      moduleKeys.set(module, (moduleKeys.get(module) || 0) + 1);

      for (const language of this.task.languages) {
        if (translation.translations[language]?.status === 'valid') {
          moduleTranslatedKeys.set(
            module,
            (moduleTranslatedKeys.get(module) || 0) + 1
          );
        }
      }
    }

    for (const [module, total] of moduleKeys.entries()) {
      const translated = moduleTranslatedKeys.get(module) || 0;
      coverage.byModule[module] = (translated / total) * 100;
    }

    // 检查缺失和冗余的键
    for (const [key, translation] of Object.entries(result.translations)) {
      const hasValidTranslation = this.task.languages.some(
        language => translation.translations[language]?.status === 'valid'
      );

      if (!hasValidTranslation) {
        coverage.missingKeys.push(key);
      }
    }

    return coverage;
  }

  /**
   * 分析使用情况
   * @param result 合并后的结果
   */
  private analyzeUsage(result: ExtractionResult): ExtractionResult['analysis']['usage'] {
    const usage = {
      highFrequency: [] as string[],
      lowFrequency: [] as string[],
      unusedKeys: [] as string[]
    };

    // 计算使用频率阈值
    const frequencies = Object.values(result.translations).map(t => t.frequency);
    const avgFrequency = frequencies.reduce((sum, f) => sum + f, 0) / frequencies.length;
    const highThreshold = avgFrequency * 1.5;
    const lowThreshold = avgFrequency * 0.5;

    // 分类键的使用情况
    for (const [key, translation] of Object.entries(result.translations)) {
      if (translation.frequency === 0) {
        usage.unusedKeys.push(key);
      } else if (translation.frequency >= highThreshold) {
        usage.highFrequency.push(key);
      } else if (translation.frequency <= lowThreshold) {
        usage.lowFrequency.push(key);
      }
    }

    return usage;
  }

  /**
   * 分析模块分布
   * @param result 合并后的结果
   */
  private analyzeModules(result: ExtractionResult): ExtractionResult['analysis']['modules'] {
    const modules: ExtractionResult['analysis']['modules'] = {};

    for (const translation of Object.values(result.translations)) {
      const module = translation.module;
      if (!modules[module]) {
        modules[module] = {
          keyCount: 0,
          usageFrequency: 0,
          coverage: 0
        };
      }

      modules[module].keyCount++;
      modules[module].usageFrequency += translation.frequency;
    }

    // 计算模块覆盖率
    for (const module of Object.keys(modules)) {
      const moduleTranslations = Object.values(result.translations).filter(
        t => t.module === module
      );
      const totalKeys = moduleTranslations.length;
      const translatedKeys = moduleTranslations.filter(t =>
        this.task.languages.some(l => t.translations[l]?.status === 'valid')
      ).length;

      modules[module].coverage = (translatedKeys / totalKeys) * 100;
    }

    return modules;
  }

  /**
   * 分析质量
   * @param result 合并后的结果
   */
  private analyzeQuality(result: ExtractionResult): ExtractionResult['analysis']['quality'] {
    const quality = {
      duplicates: [] as Array<{ key: string; occurrences: string[] }>,
      namingIssues: [] as Array<{ key: string; issue: string }>,
      contextIssues: [] as Array<{ key: string; issue: string }>
    };

    // 检查重复键
    const keyMap = new Map<string, string[]>();
    for (const [key, translation] of Object.entries(result.translations)) {
      const source = translation.source;
      if (!keyMap.has(source)) {
        keyMap.set(source, []);
      }
      keyMap.get(source)?.push(key);
    }

    for (const [source, keys] of keyMap.entries()) {
      if (keys.length > 1) {
        quality.duplicates.push({
          key: keys[0],
          occurrences: keys
        });
      }
    }

    // 检查命名问题
    for (const [key, translation] of Object.entries(result.translations)) {
      // 检查命名规范
      if (!/^[a-z][a-z0-9_]*$/.test(key)) {
        quality.namingIssues.push({
          key,
          issue: 'Key should follow snake_case naming convention'
        });
      }

      // 检查命名长度
      if (key.length > 50) {
        quality.namingIssues.push({
          key,
          issue: 'Key is too long'
        });
      }
    }

    // 检查上下文问题
    for (const [key, translation] of Object.entries(result.translations)) {
      if (!translation.context) {
        quality.contextIssues.push({
          key,
          issue: 'Missing context information'
        });
      }

      if (translation.occurrences.length === 0) {
        quality.contextIssues.push({
          key,
          issue: 'No usage information found'
        });
      }
    }

    return quality;
  }

  /**
   * 生成建议
   * @param result 合并后的结果
   */
  private generateSuggestions(result: ExtractionResult): ExtractionResult['suggestions'] {
    const suggestions: ExtractionResult['suggestions'] = [];

    // 覆盖率建议
    if (result.analysis.coverage.overall < 80) {
      suggestions.push({
        type: 'coverage',
        message: 'Translation coverage is below 80%',
        priority: 'high',
        affectedKeys: result.analysis.coverage.missingKeys
      });
    }

    // 使用情况建议
    if (result.analysis.usage.unusedKeys.length > 0) {
      suggestions.push({
        type: 'quality',
        message: `Found ${result.analysis.usage.unusedKeys.length} unused translation keys`,
        priority: 'medium',
        affectedKeys: result.analysis.usage.unusedKeys
      });
    }

    // 质量建议
    if (result.analysis.quality.duplicates.length > 0) {
      suggestions.push({
        type: 'quality',
        message: `Found ${result.analysis.quality.duplicates.length} duplicate translations`,
        priority: 'high',
        affectedKeys: result.analysis.quality.duplicates.map(d => d.key)
      });
    }

    if (result.analysis.quality.namingIssues.length > 0) {
      suggestions.push({
        type: 'quality',
        message: `Found ${result.analysis.quality.namingIssues.length} naming issues`,
        priority: 'medium',
        affectedKeys: result.analysis.quality.namingIssues.map(n => n.key)
      });
    }

    return suggestions;
  }

  /**
   * 创建空结果
   */
  private createEmptyResult(): ExtractionResult {
    return {
      taskId: this.task.taskId,
      status: 'success',
      startTime: new Date().toISOString(),
      endTime: new Date().toISOString(),
      statistics: {
        totalFiles: 0,
        processedFiles: 0,
        extractedKeys: 0,
        errors: 0,
        processingTime: 0
      },
      translations: [],
      analysis: {
        coverage: {
          overall: 0,
          byLanguage: {},
          byModule: {},
          missingKeys: [],
          redundantKeys: []
        },
        usage: {
          highFrequency: [],
          lowFrequency: [],
          unusedKeys: []
        },
        modules: {},
        quality: {
          duplicates: [],
          namingIssues: [],
          contextIssues: []
        }
      },
      errors: [],
      suggestions: []
    };
  }
} 